﻿using System;
using System.Collections;
using System.Web;
using System.Web.UI.WebControls;

namespace MyLib.Web.UI {
	/// <summary>
	/// 
	/// </summary>
	public class MyObjectDataSourceView : ObjectDataSourceView {
		private MyObjectDataSource m_owner;

		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		protected override void OnObjectCreating(ObjectDataSourceEventArgs e) {
			base.OnObjectCreating(e);

			if (e.ObjectInstance == null) {
				var mp = m_owner.Page as MyPage;

				if (mp != null) {
					var type = System.Web.Compilation.BuildManager.GetType(TypeName, false, true);

					if (type != null) {
						e.ObjectInstance = mp.HttpResource.GetDbProvider(type);
					}
				}
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		protected override void OnObjectCreated(ObjectDataSourceEventArgs e) {
			base.OnObjectCreated(e);

			if (!(e.ObjectInstance is DbContextProvider)) {
				return;
			} else {
				var instance = (DbContextProvider)e.ObjectInstance;

				if (instance.SessionFactory == null) {
					// Find DbContext.
					var parent = m_owner.Parent;
					while (parent != null) {
						if (parent is IDbContext) {
							var sessionFactory = (parent as IDbContext).SessionFactory;

							System.Diagnostics.Debug.Assert(sessionFactory != null);

							// Assign session.
							instance.SessionFactory = sessionFactory;

							return;
						}

						parent = parent.Parent;
					}

					throw new InvalidOperationException("Cannot find any IDbContext ancestor.");
				} // end of if.
			} // end of if.
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="owner"></param>
		/// <param name="viewName"></param>
		/// <param name="context"></param>
		public MyObjectDataSourceView(MyObjectDataSource owner, string viewName, HttpContext context)
			: base(owner, viewName, context) {
			System.Diagnostics.Debug.Assert(owner != null);

			m_owner = owner;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="keys"></param>
		/// <param name="values"></param>
		/// <param name="oldValues"></param>
		/// <returns></returns>
		protected override int ExecuteUpdate(IDictionary keys, IDictionary values, IDictionary oldValues) {
			foreach (System.Web.UI.WebControls.Parameter p in UpdateParameters) {
				if (p.Type == TypeCode.Decimal || p.Type == TypeCode.Double || p.Type == TypeCode.Single
					|| p.Type == TypeCode.Byte || p.Type == TypeCode.Int16 || p.Type == TypeCode.Int32 || p.Type == TypeCode.Int64
					|| p.Type == TypeCode.SByte || p.Type == TypeCode.UInt16 || p.Type == TypeCode.UInt32 || p.Type == TypeCode.UInt64) {

					var v = Convert.ToString(values[p.Name]);
					if (v == null) {
						values[p.Name] = DBNull.Value;
					} else {
						var sv = new char[v.Length];
						var df = false;
						var j = 0;
						for (int i = 0; i < v.Length; ++i) {
							var vc = v[i];
							if (vc == '.' && !df) {
								df = true;
								sv[j++] = vc;
							} else if (vc >= '0' && vc <= '9') {
								sv[j++] = vc;
							}
						}
						values[p.Name] = new string(sv, 0, j);
					} // end of if.
				} // end of if.
			} // end of for.

			try {
				return base.ExecuteUpdate(keys, values, oldValues);
			} catch (OverflowException oe) {
				throw new ApplicationException(oe.Message);
			} catch (FormatException fe) {
				throw new ApplicationException(fe.Message);
			} // end of try.
		}

	} // end of MyObjectDataSourceView.
}
